package com.ndood.polling.domain.record.receive.v1.service;

import java.math.BigDecimal;
import java.util.Date;

import org.apache.http.util.Asserts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.alipay.api.response.AlipayTradeCancelResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.ndood.common.base.constaints.CoreConstaints;
import com.ndood.common.base.util.BigDecimalUtil;
import com.ndood.common.base.util.DateUtil;
import com.ndood.common.base.util.StringUtil;
import com.ndood.polling.app.tools.IdUtils;
import com.ndood.polling.base.dao.record_receive.v1.ExtendRecoRecOfflineOrderDao;
import com.ndood.polling.base.dao.record_receive.v1.ExtendRecoRecPayDao;
import com.ndood.polling.domain.record.receive.v1.entity.dto.RecoRecFlowDto;
import com.ndood.polling.domain.record.receive.v1.entity.dto.RecoRecOfflineOrderDto;
import com.ndood.polling.domain.record.receive.v1.entity.dto.RecoRecPayDto;
import com.ndood.polling.domain.record.receive.v1.repository.RecoRecFlowRepository;
import com.ndood.polling.domain.record.receive.v1.repository.RecoRecOfflineOrderRepository;
import com.ndood.polling.domain.record.receive.v1.repository.RecoRecPayRepository;
import com.ndood.polling.domain.support.merchant.entity.dto.SupportMchRecContractDto;
import com.ndood.polling.domain.support.merchant.service.SupportMchRecContractService;

/**
 * 收款记录-平台线下官方支付宝-当面付订单记录服务
 * （实时轮询要么成功，要么撤销）
 */
@Service
public class RecoRecPlatformOfflineOfficialAlif2fService {

	@Autowired
	private RecoRecOfflineOrderRepository recoRecOfflineOrderRepository;
	
	@Autowired
	private RecoRecPayRepository recoRecPayRepository;
	
	@Autowired
	private ExtendRecoRecPayDao extendRecoRecPayDao;
	
	@Autowired
	private ExtendRecoRecOfflineOrderDao extendRecoRecOfflineOrderDao;
	
	@Autowired
	private SupportMchRecContractService supportMchRecContractService;
	
	@Autowired
	private RecoRecFlowRepository recoRecFlowRepository;
	
	@Autowired
	private IdUtils idUtils;
	
	/**
	 * 1 记录轮询撤销
	 */
	@Transactional
	public void pollingCancel(RecoRecPayDto payOrder, AlipayTradeCancelResponse response) {
		// Step1: 生成订单
		RecoRecOfflineOrderDto o = new RecoRecOfflineOrderDto();
		o.setOrderNo(payOrder.getOrderNo());
		o.setStatus(CoreConstaints.REC_ORDER_STATUS_CANCEL);
		recoRecOfflineOrderRepository.updateRecOfflineOrder(o);
		
		// Step3: 生成支付订单
		RecoRecPayDto p = new RecoRecPayDto();
		p.setPayOrderNo(payOrder.getPayOrderNo());
		p.setStatus(CoreConstaints.REC_CHANNEL_STATUS_CREATE);
		recoRecPayRepository.updateRecPay(p);
	}

	/**
	 * 2 记录异常订单
	 */
	@Transactional
	public void pollingCancelFailed(RecoRecPayDto payOrder, AlipayTradeQueryResponse response) {
		// Step1: 生成订单
		RecoRecOfflineOrderDto o = new RecoRecOfflineOrderDto();
		o.setOrderNo(payOrder.getOrderNo());
		o.setStatus(CoreConstaints.REC_ORDER_STATUS_FAILED);
		o.setParam1(StringUtil.substring(response.getSubCode(),50));
		o.setParam2(StringUtil.substring(response.getSubMsg(),50));
		o.setIsManual(1);
		recoRecOfflineOrderRepository.updateRecOfflineOrder(o);
		
		// Step3: 生成支付订单
		RecoRecPayDto p = new RecoRecPayDto();
		p.setPayOrderNo(payOrder.getPayOrderNo());
		p.setStatus(CoreConstaints.REC_CHANNEL_STATUS_FAILED);
		p.setParam1(o.getParam1());
		p.setParam2(o.getParam2());
		o.setIsManual(1);
		recoRecPayRepository.updateRecPay(p);
	}
	
	/**
	 * 3 记录支付成功
	 */
	public void pollingSuccess(RecoRecPayDto payOrder, AlipayTradeQueryResponse response) {
		// Step1: 获取参数
		String buyer_id = response.getBuyerUserId();
		String buyer_logon_id = response.getBuyerLogonId();
		String receipt_amount = response.getReceiptAmount();
		String buyer_pay_amount = response.getBuyerPayAmount();
		Date gmt_payment = new Date();
		
		// Step2: 提取出关键变量并进行计算
		String payOrderNo = payOrder.getPayOrderNo();
		RecoRecPayDto p = extendRecoRecPayDao.extendFindReceivePayByPayOrderNo(payOrderNo);
		Asserts.notNull(p, "渠道订单不存在！");
		RecoRecOfflineOrderDto o = extendRecoRecOfflineOrderDao.extendFindOfflineOrderByOrderNo(p.getOrderNo());
		Asserts.notNull(o, "订单不存在！");
		if(!CoreConstaints.REC_ORDER_STATUS_PAYING.equals(o.getStatus())) {
			// 只处理支付中的订单
			return;
		}
		
		// Step3: 提取出关键变量并进行计算
		p.setParam1(payOrder.getParam1());
		p.setPayTime(DateUtil.format(gmt_payment));
		p.setReceiptAmount(new BigDecimal(receipt_amount)); // 商户实收
		p.setFreeAmount(BigDecimalUtil.sub(p.getTotalAmount(), p.getReceiptAmount())); // 商户优惠 = 总金额 - 商户实收
		p.setBuyerPayAmount(new BigDecimal(buyer_pay_amount)); // 买家实付
		p.setThirdFreeAmount(BigDecimalUtil.sub(p.getReceiptAmount(), p.getBuyerPayAmount())); // 接口优惠 = 商户实收 - 买家实付
		p.setBuyerLogonId(buyer_logon_id);
		p.setBuyerUserId(buyer_id);
		p.setStatus(CoreConstaints.REC_CHANNEL_STATUS_SUCCESS);
		recoRecPayRepository.updateRecPay(p);
		
		o.setParam1(p.getParam1());
		o.setReceiptAmount(p.getReceiptAmount());
		o.setCanRefundAmount(o.getTotalAmount());
		o.setFreeAmount(p.getFreeAmount());
		o.setLastPayTime(DateUtil.format(gmt_payment));
		o.setStatus(CoreConstaints.REC_ORDER_STATUS_SUCCESS);
		o.setPay(p);
		recoRecOfflineOrderRepository.updateRecOfflineOrder(o);
		
		// Step3: 支付成功记录交易流水
		RecoRecFlowDto flow = new RecoRecFlowDto();
		flow.setFlowNo(idUtils.getNextId());
		flow.setTradeNo(p.getPayOrderNo());
		flow.setAgentId(o.getAgentId());
		flow.setAgentName(o.getAgentName());
		flow.setChannelId(p.getChannelId());
		flow.setChannelName(p.getChannelName());
		flow.setChannelNo(p.getChannelNo());
		flow.setContractId(p.getContractId());
		flow.setContractName(p.getContractName());
		flow.setContractNo(p.getContractNo());
		flow.setContractType(p.getContractType());
		flow.setMchId(o.getMchId());
		flow.setMchName(o.getMchName());
		flow.setOrderNo(o.getOrderNo());
		flow.setPayType(p.getPayType());
		flow.setPayWay(p.getPayWay());
		flow.setProductName(p.getProductName());
		flow.setProductNo(p.getProductNo());
		flow.setShopId(o.getShopId());
		flow.setShopName(o.getShopName());
		flow.setTradeAmount(p.getTotalAmount());
		flow.setTradeTime(p.getPayTime());
		flow.setTradeType(CoreConstaints.TRADE_TYPE_REC_PAY);
		
		// 查询出支付商户合同信息
		SupportMchRecContractDto contract = supportMchRecContractService.getMerchantReceiveContract(p.getContractId());
		Assert.notNull(contract, "商户收款合同不存在");
		
		flow.setSettleStatus(CoreConstaints.SETTLE_STATUS_INIT);
		flow.setSettleType(contract.getSettleType());
		flow.setSettleRate(contract.getRate());
		flow.setSettleRiskDay(contract.getRiskDay());
		flow.setSettleDate(DateUtil.getAfterDate(new Date(), 0, flow.getSettleRiskDay(), 0, 0, 0));
		if(CoreConstaints.SETTLE_TYPE_SOLID.equals(flow.getSettleType())){
			flow.setSettleAgentRate(new BigDecimal(0));
			flow.setSettlePlatformRate(new BigDecimal(0));
			flow.setSettleAgentFee(contract.getAgentFee()); 
			flow.setSettlePlatformFee(contract.getPlatformFee());
			flow.setSettlePlatformProfit(flow.getSettlePlatformFee());
			flow.setSettleAgentProfit(flow.getSettleAgentFee());
		} else {
			flow.setSettleAgentFee(new BigDecimal(0)); 
			flow.setSettlePlatformFee(new BigDecimal(0));
			flow.setSettleAgentRate(contract.getAgentRate());
			flow.setSettlePlatformRate(contract.getPlatformRate());
			flow.setSettlePlatformProfit(BigDecimalUtil.mul(flow.getTradeAmount(), flow.getSettlePlatformRate()));
			flow.setSettleAgentProfit(BigDecimalUtil.mul(flow.getTradeAmount(), flow.getSettleAgentRate()));
		}
		flow.setSettleMchProfit(BigDecimalUtil.sub(flow.getTradeAmount(), BigDecimalUtil.add(flow.getSettlePlatformProfit(), flow.getSettleAgentProfit())));
		recoRecFlowRepository.insertRecFlow(flow);	
	}

	
}
